package cn.selfiot.iotman.view.console;

import cn.selfiot.iotman.view.ResourceConstants;
import org.fxmisc.richtext.model.StyleSpans;
import org.fxmisc.richtext.model.StyleSpansBuilder;

import java.util.Collection;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Console 高亮解析
 *
 * @author hugo
 * @since 2020/8/6
 */
public class ConsoleParser {
    private static final String DEBUG_PATTERN = "DEBUG";
    private static final String INFO_PATTERN = "INFO";
    private static final String WARN_PATTERN = "WARN";
    private static final String ERROR_PATTERN = "ERROR";
    
    private static final Pattern PATTERN = Pattern.compile(
            "(?<DEBUG>" + DEBUG_PATTERN + ")"
                    + "|(?<INFO>" + INFO_PATTERN + ")"
                    + "|(?<WARN>" + WARN_PATTERN + ")"
                    + "|(?<ERROR>" + ERROR_PATTERN + ")"
    );
    
    public String getStylesheets() {
        return this.getClass()
                .getResource(ResourceConstants.STYLE_HIGHLIGHT_CONSOLE)
                .toExternalForm();
    }
    
    public StyleSpans<Collection<String>> computeHighlighting(String code) {
        Matcher matcher;
        try {
            matcher = PATTERN.matcher(code);
        } catch (Exception e) {
            return null;
        }
        
        int lastKwEnd = 0;
        StyleSpansBuilder<Collection<String>> spansBuilder =
                new StyleSpansBuilder<>();
        while (matcher.find()) {
            String styleClass
                    = matcher.group("DEBUG") != null ? "debug"
                    : matcher.group("INFO") != null ? "info"
                    : matcher.group("WARN") != null ? "warn"
                    : matcher.group("ERROR") != null ? "error"
                    : null;
            
            spansBuilder.add(Collections.emptyList(),
                    matcher.start() - lastKwEnd);
            spansBuilder.add(Collections.singleton(styleClass),
                    matcher.end() - matcher.start());
            lastKwEnd = matcher.end();
        }
        spansBuilder.add(Collections.emptyList(),
                code.length() - lastKwEnd);
        return spansBuilder.create();
    }
}
